package net.cyue.homework.student.management.db;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.function.Consumer;


public class ConnectionWrapper {
    private static int WRAPPER_COUNT = 0;

    private final int id = ++WRAPPER_COUNT;
    private final Connection connection;
    private boolean thisUsing = false;
    private boolean connectionUsing = false;

    public ConnectionWrapper(Connection connection) throws NullPointerException {
        if (connection == null) {
            throw new NullPointerException("connection 为空");
        }
        this.connection = connection;
    }
    public boolean isUsing() {
        return this.thisUsing;
    }
    public boolean isConnectionUsing() {
        return this.connectionUsing;
    }
    public boolean isClosed() {
        try {
            return this.connection.isClosed();
        } catch (SQLException e) {
            return true;
        }
    }
    public boolean isValid(int timeout) {
        try {
            return this.connection.isValid(timeout);
        } catch (SQLException e) {
            return false;
        }
    }


    public synchronized Connection getConnection() throws ConnectionBusyException {
        if (this.connectionUsing) {
            throw new ConnectionBusyException("connection 正在被使用");
        }
        this.busy();
        this.connectionUsing = true;
        return this.connection;
    }
    public void busy() {
        this.thisUsing = true;
    }
    public void free() {
        this.thisUsing = false;
        this.connectionUsing = false;
    }


    public void close() {
        try {
            if (this.connection.isClosed()) {
                return;
            }
            System.out.println("关闭数据库连接" + this.id);
            this.connection.close();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    public synchronized void useConnection(Consumer<Connection> work) {
        if (!this.connectionUsing) {
            try {
                Connection connection = this.getConnection();
                work.accept(connection);
                this.free();
            } catch (ConnectionBusyException e) {
                e.printStackTrace();
            }
            return;
        }

        new Thread(() -> {
            try {
                while (this.connectionUsing) {
                    Thread.sleep(500);
                }
                Connection connection = this.getConnection();
                work.accept(connection);
                this.free();
            } catch (InterruptedException | ConnectionBusyException e) {
                e.printStackTrace();
            }
        });

    }

}


